<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from "vue";
import {
  reqRoleList,
  reqAddOrUpdateRole,
  reqMenuList,
  reqSetMission,
  reqRemoveRole,
} from "@/api/acl/role";
import useLayoutStore from "@/store/modules/layout";
import { ElMessage } from "element-plus";
// layoutStore
const layoutStore = useLayoutStore();
let pageNo = ref<number>(1);
let pageSize = ref<number>(3);
let total = ref<number>(0);
// 职位搜素所收集的字段
let keyword = ref<string>("");
// 控制dialog显示与隐藏的字段
const dialogShow = ref<boolean>(false);
// roleList
let roleList = ref<any[]>([]);
// roleParams
let roleParams = reactive<any>({
  roleName: "",
});
// el-form组件实例
let form = ref<any>();
// el-tree组件实例
let tree = ref<any>();
// 控制 el-drawer 显示与隐藏的字段
let drawerShow = ref<boolean>(false);
// menuList
let menuList = ref<any[]>([]);
// 供tree树形控件初始化勾选的数组
let selectArr = ref<number[]>([]);
// onMounted
onMounted(() => {
  getRoleList();
});
// 封装出获取角色分页列表的方法
const getRoleList = async (pager = 1) => {
  pageNo.value = pager;
  let res: any = await reqRoleList(pageNo.value, pageSize.value, keyword.value);
  if (res.code == 200) {
    roleList.value = res.data.records;
    total.value = res.data.total;
  }
};
// el-table每一页展示数据条数发生变化时的回调
const handleSizeChange = () => {
  getRoleList();
};
// 点击搜素按钮的回调
const search = () => {
  getRoleList();
  keyword.value = "";
};
// 点击重置按钮的回调
const reset = () => {
  layoutStore.refresh = !layoutStore.refresh;
};
// 点击添加职位按钮的回调
const addRole = () => {
  roleParams.id = 0;
  roleParams.roleName = "";
  dialogShow.value = true;
  nextTick(() => {
    form.value.clearValidate("roleName");
  });
};
// dialog添加职位的确定按钮的回调
const confirm = async () => {
  await form.value.validate();
  let res: any = await reqAddOrUpdateRole(roleParams);
  if (res.code == 200) {
    dialogShow.value = false;
    ElMessage({
      type: "success",
      message: roleParams.id ? "修改成功" : "添加成功",
    });
    getRoleList(roleParams.id ? pageNo.value : 1);
  }
};
// 点击编辑(修改职位)的按钮的回调
const updateRole = async (role: any) => {
  Object.assign(roleParams, role);
  dialogShow.value = true;
  nextTick(() => {
    form.value.clearValidate("roleName");
  });
};
// 一个返回供tree树形控件初始化勾选的数组的方法
const filterMenuList = (allData: any, initArr: any) => {
  allData.forEach((item: any) => {
    if (item.select && item.level == 4) {
      initArr.push(item.id);
    }
    if (item.children && item.children.length > 0) {
      filterMenuList(item.children, initArr);
    }
  });
  return initArr;
};
// 点击分配权限的按钮的回调
const setPermission = async (row: any) => {
  Object.assign(roleParams, row);
  drawerShow.value = true;
  let res: any = await reqMenuList(row.id);
  if (res.code == 200) {
    menuList.value = res.data;
    selectArr.value = filterMenuList(menuList.value, []);
  }
};
// 点击 el-drawer 组件的确定按钮的回调
const handleConfirm = async () => {
  let checkedArr: any[] = tree.value
    .getCheckedNodes()
    .map((item: any): any[] => item.id);
  let halfCheckedArr = tree.value
    .getHalfCheckedNodes()
    .map((item: any) => item.id);
  let allArr: any[] = checkedArr.concat(halfCheckedArr);
  let res: any = await reqSetMission(roleParams.id, allArr);
  if (res.code == 200) {
    drawerShow.value = false;
    ElMessage({
      type: "success",
      message: "修改权限成功",
    });
    window.location.reload();
  } else {
    ElMessage({
      type: "error",
      message: "系统权限,无法修改",
    });
  }
};
// 点击删除(职位)按钮的回调
const removeRole = async (id: number) => {
  let res: any = await reqRemoveRole(id);
  if (res.code == 200) {
    ElMessage({
      type: "success",
      message: "删除职位成功",
    });
    getRoleList(roleList.value.length > 1 ? pageNo.value : pageNo.value - 1);
  } else {
    ElMessage({
      type: "error",
      message: "删除职位失败",
    });
  }
};
// validatorRoleName
const validatorRoleName = (rule: any, value: any, callback: any) => {
  if (value.trim().length >= 2) {
    callback();
  } else {
    callback(new Error("职位名称必须大于等于两位"));
  }
};
// rules表单验证规则对象
let rules = {
  roleName: [{ required: true, trigger: "blur", validator: validatorRoleName }],
};
// 树形控件配置选项
const defaultProps = {
  children: "children",
  label: "name",
};
</script>

<template>
  <div>
    <el-card>
      <el-form inline class="form">
        <el-form-item label="职位搜素">
          <el-input
            v-model="keyword"
            placeholder="请输入搜素职位关键字"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            :disabled="keyword ? false : true"
            @click="search"
            >搜素</el-button
          >
          <el-button type="primary" @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card style="margin: 10px 0">
      <el-button
        type="primary"
        icon="Plus"
        @click="addRole"
        v-have="`btn.Role.add`"
        >添加职位</el-button
      >
      <el-table style="margin: 10px 0" border :data="roleList">
        <el-table-column
          label="#"
          type="index"
          align="center"
        ></el-table-column>
        <el-table-column label="ID" align="center" prop="id"></el-table-column>
        <el-table-column
          label="职位名称"
          align="center"
          prop="roleName"
        ></el-table-column>
        <el-table-column
          label="创建时间"
          align="center"
          prop="createTime"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          label="更新时间"
          align="center"
          prop="updateTime"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column label="操作" align="center" width="250px">
          <template v-slot="{ row, $index }">
            <el-button
              type="primary"
              size="small"
              icon="User"
              @click="setPermission(row)"
              >分配权限</el-button
            >
            <el-button
              type="primary"
              size="small"
              icon="Edit"
              @click="updateRole(row)"
              v-have="`btn.Role.update`"
              >编辑</el-button
            >
            <el-popconfirm
              :title="`您确定要删除${row.roleName}吗?`"
              width="250px"
              icon="Delete"
              @confirm="removeRole(row.id)"
            >
              <template #reference>
                <el-button
                  type="primary"
                  size="small"
                  icon="Delete"
                  v-have="`btn.Role.remove`"
                  >删除</el-button
                >
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="pageSize"
        :page-sizes="[3, 5, 7]"
        background
        layout="prev, pager, next, jumper,->,sizes,total"
        :total="total"
        @current-change="getRoleList"
        @size-change="handleSizeChange"
      ></el-pagination>
    </el-card>
    <el-dialog
      v-model="dialogShow"
      :title="roleParams.id ? '修改职位' : '添加职位'"
    >
      <el-form :model="roleParams" :rules="rules" ref="form">
        <el-form-item label="职位名称" prop="roleName">
          <el-input
            placeholder="请输入职位名称"
            v-model="roleParams.roleName"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogShow = false">取消</el-button>
        <el-button type="primary" @click="confirm"> 确定 </el-button>
      </template>
    </el-dialog>
    <el-drawer v-model="drawerShow">
      <template #header>
        <h4>分配菜单与按钮的权限</h4>
      </template>
      <template #default>
        <el-tree
          ref="tree"
          :data="menuList"
          show-checkbox
          node-key="id"
          default-expand-all
          :default-checked-keys="selectArr"
          :props="defaultProps"
        />
      </template>
      <template #footer>
        <el-button @click="drawerShow = false">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确定</el-button>
      </template>
    </el-drawer>
  </div>
</template>

<style scoped>
.form {
  height: 50px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
